package com.bc.trade.channel.suning.util;

import java.io.UnsupportedEncodingException;

public class MD5SRC extends CoderBase {
	private static final long A = 1732584193L;
	private static final long B = 4023233417L;
	private static final long C = 2562383102L;
	private static final long D = 271733878L;
	private static final String[] HEXS = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C",
			"D", "E", "F"};
	private static final int S11 = 7;
	private static final int S12 = 12;
	private static final int S13 = 17;
	private static final int S14 = 22;
	private static final int S21 = 5;
	private static final int S22 = 9;
	private static final int S23 = 14;
	private static final int S24 = 20;
	private static final int S31 = 4;
	private static final int S32 = 11;
	private static final int S33 = 16;
	private static final int S34 = 23;
	private static final int S41 = 6;
	private static final int S42 = 10;
	private static final int S43 = 15;
	private static final int S44 = 21;
	private static final int GROUP_IX_0 = 0;
	private static final int GROUP_IX_1 = 1;
	private static final int GROUP_IX_2 = 2;
	private static final int GROUP_IX_3 = 3;
	private static final int GROUP_IX_4 = 4;
	private static final int GROUP_IX_5 = 5;
	private static final int GROUP_IX_6 = 6;
	private static final int GROUP_IX_7 = 7;
	private static final int GROUP_IX_8 = 8;
	private static final int GROUP_IX_9 = 9;
	private static final int GROUP_IX_10 = 10;
	private static final int GROUP_IX_11 = 11;
	private static final int GROUP_IX_12 = 12;
	private static final int GROUP_IX_13 = 13;
	private static final int GROUP_IX_14 = 14;
	private static final int GROUP_IX_15 = 15;
	private static final long[] RESULT = new long[]{1732584193L, 4023233417L, 2562383102L, 271733878L};

	public static String digest(String inputStr, String charset) throws UnsupportedEncodingException {
		long len;
		int i;
		byte[] inputBytes = null;
		inputBytes = inputStr.getBytes(charset);
		int byteLen = inputBytes.length;
		int groupCount = byteLen / 64;
		long[] groups = null;
		for (int step = 0; step < groupCount; ++step) {
			groups = MD5SRC.divGroup(inputBytes, step * 64);
			MD5SRC.trans(groups);
		}
		int rest = byteLen % 64;
		byte[] tempBytes = new byte[64];
		if (rest <= 56) {
			int i2;
			for (i2 = 0; i2 < rest; ++i2) {
				tempBytes[i2] = inputBytes[byteLen - rest + i2];
			}
			if (rest < 56) {
				tempBytes[rest] = -128;
				for (i2 = 1; i2 < 56 - rest; ++i2) {
					tempBytes[rest + i2] = 0;
				}
			}
			len = byteLen << 3;
			for (i = 0; i < 8; ++i) {
				tempBytes[56 + i] = (byte) (len & 255L);
				len >>= 8;
			}
			groups = MD5SRC.divGroup(tempBytes, 0);
			MD5SRC.trans(groups);
		} else {
			int i3;
			for (i3 = 0; i3 < rest; ++i3) {
				tempBytes[i3] = inputBytes[byteLen - rest + i3];
			}
			tempBytes[rest] = -128;
			for (i3 = rest + 1; i3 < 64; ++i3) {
				tempBytes[i3] = 0;
			}
			groups = MD5SRC.divGroup(tempBytes, 0);
			MD5SRC.trans(groups);
			for (i3 = 0; i3 < 56; ++i3) {
				tempBytes[i3] = 0;
			}
			len = byteLen << 3;
			for (i = 0; i < 8; ++i) {
				tempBytes[56 + i] = (byte) (len & 255L);
				len >>= 8;
			}
			groups = MD5SRC.divGroup(tempBytes, 0);
			MD5SRC.trans(groups);
		}
		StringBuffer resStr = new StringBuffer();
		long temp = 0L;
		for (int i4 = 0; i4 < 4; ++i4) {
			for (int j = 0; j < 4; ++j) {
				temp = RESULT[i4] & 15L;
				String a = HEXS[(int) temp];
				MD5SRC.RESULT[i4] = RESULT[i4] >> 4;
				temp = RESULT[i4] & 15L;
				resStr.append(HEXS[(int) temp] + a);
				MD5SRC.RESULT[i4] = RESULT[i4] >> 4;
			}
		}
		return resStr.toString();
	}

	private static long[] divGroup(byte[] inputBytes, int index) {
		long[] temp = new long[16];
		for (int i = 0; i < 16; ++i) {
			temp[i] = MD5SRC.b2iu(inputBytes[4 * i + index]) | MD5SRC.b2iu(inputBytes[4 * i + 1 + index]) << 8
					| MD5SRC.b2iu(inputBytes[4 * i + 2 + index]) << 16
					| MD5SRC.b2iu(inputBytes[4 * i + 3 + index]) << 24;
		}
		return temp;
	}

	public static long b2iu(byte b) {
		return b < 0 ? (long) (b & 255) : (long) b;
	}

	private static void trans(long[] groups) {
		long a = RESULT[0];
		long b = RESULT[1];
		long c = RESULT[2];
		long d = RESULT[3];
		a = MD5SRC.ff(a, b, c, d, groups[0], 7L, 3614090360L);
		d = MD5SRC.ff(d, a, b, c, groups[1], 12L, 3905402710L);
		c = MD5SRC.ff(c, d, a, b, groups[2], 17L, 606105819L);
		b = MD5SRC.ff(b, c, d, a, groups[3], 22L, 3250441966L);
		a = MD5SRC.ff(a, b, c, d, groups[4], 7L, 4118548399L);
		d = MD5SRC.ff(d, a, b, c, groups[5], 12L, 1200080426L);
		c = MD5SRC.ff(c, d, a, b, groups[6], 17L, 2821735955L);
		b = MD5SRC.ff(b, c, d, a, groups[7], 22L, 4249261313L);
		a = MD5SRC.ff(a, b, c, d, groups[8], 7L, 1770035416L);
		d = MD5SRC.ff(d, a, b, c, groups[9], 12L, 2336552879L);
		c = MD5SRC.ff(c, d, a, b, groups[10], 17L, 4294925233L);
		b = MD5SRC.ff(b, c, d, a, groups[11], 22L, 2304563134L);
		a = MD5SRC.ff(a, b, c, d, groups[12], 7L, 1804603682L);
		d = MD5SRC.ff(d, a, b, c, groups[13], 12L, 4254626195L);
		c = MD5SRC.ff(c, d, a, b, groups[14], 17L, 2792965006L);
		b = MD5SRC.ff(b, c, d, a, groups[15], 22L, 1236535329L);
		a = MD5SRC.gg(a, b, c, d, groups[1], 5L, 4129170786L);
		d = MD5SRC.gg(d, a, b, c, groups[6], 9L, 3225465664L);
		c = MD5SRC.gg(c, d, a, b, groups[11], 14L, 643717713L);
		b = MD5SRC.gg(b, c, d, a, groups[0], 20L, 3921069994L);
		a = MD5SRC.gg(a, b, c, d, groups[5], 5L, 3593408605L);
		d = MD5SRC.gg(d, a, b, c, groups[10], 9L, 38016083L);
		c = MD5SRC.gg(c, d, a, b, groups[15], 14L, 3634488961L);
		b = MD5SRC.gg(b, c, d, a, groups[4], 20L, 3889429448L);
		a = MD5SRC.gg(a, b, c, d, groups[9], 5L, 568446438L);
		d = MD5SRC.gg(d, a, b, c, groups[14], 9L, 3275163606L);
		c = MD5SRC.gg(c, d, a, b, groups[3], 14L, 4107603335L);
		b = MD5SRC.gg(b, c, d, a, groups[8], 20L, 1163531501L);
		a = MD5SRC.gg(a, b, c, d, groups[13], 5L, 2850285829L);
		d = MD5SRC.gg(d, a, b, c, groups[2], 9L, 4243563512L);
		c = MD5SRC.gg(c, d, a, b, groups[7], 14L, 1735328473L);
		b = MD5SRC.gg(b, c, d, a, groups[12], 20L, 2368359562L);
		a = MD5SRC.hh(a, b, c, d, groups[5], 4L, 4294588738L);
		d = MD5SRC.hh(d, a, b, c, groups[8], 11L, 2272392833L);
		c = MD5SRC.hh(c, d, a, b, groups[11], 16L, 1839030562L);
		b = MD5SRC.hh(b, c, d, a, groups[14], 23L, 4259657740L);
		a = MD5SRC.hh(a, b, c, d, groups[1], 4L, 2763975236L);
		d = MD5SRC.hh(d, a, b, c, groups[4], 11L, 1272893353L);
		c = MD5SRC.hh(c, d, a, b, groups[7], 16L, 4139469664L);
		b = MD5SRC.hh(b, c, d, a, groups[10], 23L, 3200236656L);
		a = MD5SRC.hh(a, b, c, d, groups[13], 4L, 681279174L);
		d = MD5SRC.hh(d, a, b, c, groups[0], 11L, 3936430074L);
		c = MD5SRC.hh(c, d, a, b, groups[3], 16L, 3572445317L);
		b = MD5SRC.hh(b, c, d, a, groups[6], 23L, 76029189L);
		a = MD5SRC.hh(a, b, c, d, groups[9], 4L, 3654602809L);
		d = MD5SRC.hh(d, a, b, c, groups[12], 11L, 3873151461L);
		c = MD5SRC.hh(c, d, a, b, groups[15], 16L, 530742520L);
		b = MD5SRC.hh(b, c, d, a, groups[2], 23L, 3299628645L);
		a = MD5SRC.ii(a, b, c, d, groups[0], 6L, 4096336452L);
		d = MD5SRC.ii(d, a, b, c, groups[7], 10L, 1126891415L);
		c = MD5SRC.ii(c, d, a, b, groups[14], 15L, 2878612391L);
		b = MD5SRC.ii(b, c, d, a, groups[5], 21L, 4237533241L);
		a = MD5SRC.ii(a, b, c, d, groups[12], 6L, 1700485571L);
		d = MD5SRC.ii(d, a, b, c, groups[3], 10L, 2399980690L);
		c = MD5SRC.ii(c, d, a, b, groups[10], 15L, 4293915773L);
		b = MD5SRC.ii(b, c, d, a, groups[1], 21L, 2240044497L);
		a = MD5SRC.ii(a, b, c, d, groups[8], 6L, 1873313359L);
		d = MD5SRC.ii(d, a, b, c, groups[15], 10L, 4264355552L);
		c = MD5SRC.ii(c, d, a, b, groups[6], 15L, 2734768916L);
		b = MD5SRC.ii(b, c, d, a, groups[13], 21L, 1309151649L);
		a = MD5SRC.ii(a, b, c, d, groups[4], 6L, 4149444226L);
		d = MD5SRC.ii(d, a, b, c, groups[11], 10L, 3174756917L);
		c = MD5SRC.ii(c, d, a, b, groups[2], 15L, 718787259L);
		b = MD5SRC.ii(b, c, d, a, groups[9], 21L, 3951481745L);
		long[] arrl = RESULT;
		arrl[0] = arrl[0] + a;
		long[] arrl2 = RESULT;
		arrl2[1] = arrl2[1] + b;
		long[] arrl3 = RESULT;
		arrl3[2] = arrl3[2] + c;
		long[] arrl4 = RESULT;
		arrl4[3] = arrl4[3] + d;
		MD5SRC.RESULT[0] = RESULT[0] & 0xFFFFFFFFL;
		MD5SRC.RESULT[1] = RESULT[1] & 0xFFFFFFFFL;
		MD5SRC.RESULT[2] = RESULT[2] & 0xFFFFFFFFL;
		MD5SRC.RESULT[3] = RESULT[3] & 0xFFFFFFFFL;
	}

	private static long f(long x, long y, long z) {
		return x & y | (x ^ -1L) & z;
	}

	private static long g(long x, long y, long z) {
		return x & z | y & (z ^ -1L);
	}

	private static long h(long x, long y, long z) {
		return x ^ y ^ z;
	}

	private static long i(long x, long y, long z) {
		return y ^ (x | z ^ -1L);
	}

	private static long ff(long a, long b, long c, long d, long x, long s, long ac) {
		long temp = a;
		temp += (MD5SRC.f(b, c, d) & 0xFFFFFFFFL) + x + ac;
		temp = (temp & 0xFFFFFFFFL) << (int) s | (temp & 0xFFFFFFFFL) >>> (int) (32L - s);
		return (temp += b) & 0xFFFFFFFFL;
	}

	private static long gg(long a, long b, long c, long d, long x, long s, long ac) {
		long temp = a;
		temp += (MD5SRC.g(b, c, d) & 0xFFFFFFFFL) + x + ac;
		temp = (temp & 0xFFFFFFFFL) << (int) s | (temp & 0xFFFFFFFFL) >>> (int) (32L - s);
		return (temp += b) & 0xFFFFFFFFL;
	}

	private static long hh(long a, long b, long c, long d, long x, long s, long ac) {
		long temp = a;
		temp += (MD5SRC.h(b, c, d) & 0xFFFFFFFFL) + x + ac;
		temp = (temp & 0xFFFFFFFFL) << (int) s | (temp & 0xFFFFFFFFL) >>> (int) (32L - s);
		return (temp += b) & 0xFFFFFFFFL;
	}

	private static long ii(long a, long b, long c, long d, long x, long s, long ac) {
		long temp = a;
		temp += (MD5SRC.i(b, c, d) & 0xFFFFFFFFL) + x + ac;
		temp = (temp & 0xFFFFFFFFL) << (int) s | (temp & 0xFFFFFFFFL) >>> (int) (32L - s);
		return (temp += b) & 0xFFFFFFFFL;
	}
}